home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / Source / Arashi 1.1 Source / For your think c folder / Juri's Class Library / CNumberFormatter.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-02  |  5.6 KB  |  290 lines  |  [TEXT/KAHL]

  1. /*/
  2.      Project Arashi: CNumberFormatter.c
  3.      Major release: Version 1.1, 7/22/92
  4.  
  5.      Last modification: Sunday, May 2, 1993, 14:05
  6.      Created: Monday, November 30, 1992, 0:22
  7.  
  8.      Copyright © 1992-1993, Juri Munkki
  9. /*/
  10.  
  11. #include "CNumberFormatter.h"
  12. #include "Numbers.h"
  13.  
  14. void    CNumberFormatter :: INumberFormatter()
  15. {
  16.     unsigned char    emptyString[] = {0};
  17.  
  18.     IBaseObject();
  19.     
  20.     SetDecimals(20,2,2);
  21.  
  22.     SetFormatString("\p$-1.0E)£");
  23.  
  24.     SetNegativeStrings("\p-",emptyString);
  25.     SetPositiveStrings("\p+",emptyString);
  26.     SetCurrencyStrings("\p",emptyString);
  27.     SetSeparatorStrings("\p","\p.");
  28.     
  29.     setround(TONEAREST);
  30. }
  31.  
  32. void    CNumberFormatter :: SetDecimals(
  33.     short    iPart,
  34.     short    min,
  35.     short    max)
  36. {
  37.     integerPart = iPart;
  38.     if(min < 0) min = 0;
  39.  
  40.     if(max > 19) max = 19;
  41.     if(min > 19) min = 19;
  42.  
  43.     if(min > max) max = min;
  44.     
  45.     maxDecimals = max;
  46.     minDecimals = min;
  47. }
  48. void    CNumberFormatter :: SetFormatString(
  49.     StringPtr    format)
  50. {
  51.     int        len;
  52.     
  53.     len = *(unsigned char *)format;
  54.     if(len >= SUBFORMATLEN)
  55.         len = SUBFORMATLEN-1;
  56.  
  57.     BlockMove(format, formatString, len+1);
  58. }
  59.  
  60. void    CNumberFormatter :: SetNegativeStrings(
  61.     StringPtr    pre,
  62.     StringPtr    post)
  63. {
  64.     int        len;
  65.     
  66.     len = *(unsigned char *)pre;
  67.     if(len >= SUBFORMATLEN)
  68.         len = SUBFORMATLEN-1;
  69.  
  70.     BlockMove(pre, negativePrefix, len+1);
  71.     
  72.     len = *(unsigned char *)post;
  73.     if(len >= SUBFORMATLEN)
  74.         len = SUBFORMATLEN-1;
  75.  
  76.     BlockMove(post, negativePostfix, len+1);
  77.  
  78. }
  79. void    CNumberFormatter :: SetPositiveStrings(
  80.     StringPtr    pre,
  81.     StringPtr    post)
  82. {
  83.     int        len;
  84.     
  85.     len = *(unsigned char *)pre;
  86.     if(len >= SUBFORMATLEN)
  87.         len = SUBFORMATLEN-1;
  88.  
  89.     BlockMove(pre, positivePrefix, len+1);
  90.     
  91.     len = *(unsigned char *)post;
  92.     if(len >= SUBFORMATLEN)
  93.         len = SUBFORMATLEN-1;
  94.  
  95.     BlockMove(post, positivePostfix, len+1);
  96.  
  97. }
  98. void    CNumberFormatter :: SetCurrencyStrings(
  99.     StringPtr    pre,
  100.     StringPtr    post)
  101. {
  102.     int        len;
  103.     
  104.     len = *(unsigned char *)pre;
  105.     if(len >= SUBFORMATLEN)
  106.         len = SUBFORMATLEN-1;
  107.  
  108.     BlockMove(pre, currencyPrefix, len+1);
  109.     
  110.     len = *(unsigned char *)post;
  111.     if(len >= SUBFORMATLEN)
  112.         len = SUBFORMATLEN-1;
  113.  
  114.     BlockMove(post, currencyPostfix, len+1);
  115. }
  116.  
  117. void    CNumberFormatter :: SetSeparatorStrings(
  118.     StringPtr    thousands,
  119.     StringPtr    decimals)
  120. {
  121.     int        len;
  122.     
  123.     len = *(unsigned char *)thousands;
  124.     if(len >= SUBFORMATLEN)
  125.         len = SUBFORMATLEN-1;
  126.  
  127.     BlockMove(thousands, thousandsSeparator, len+1);
  128.     
  129.     len = *(unsigned char *)decimals;
  130.     if(len >= SUBFORMATLEN)
  131.         len = SUBFORMATLEN-1;
  132.  
  133.     BlockMove(decimals, decimalSign, len+1);
  134. }
  135.  
  136. void    AppendBytes(
  137.     StringPtr        dest,
  138.     int                count,
  139.     void            *bytes)
  140. {
  141.     if(count + dest[0] > 255)
  142.     {    count = 255 - dest[0];
  143.     }
  144.     
  145.     if(count > 0)
  146.     {    BlockMove(bytes, dest+dest[0]+1, count);
  147.         dest[0]+= count;
  148.     }
  149. }
  150.     
  151.  
  152. void    CNumberFormatter::FormatNumber(
  153.     long double        n,
  154.     StringPtr         dest)
  155. {
  156.     decimal        myDecimals;
  157.     int            fmIndex;
  158.     int            i,j;
  159.     short        numDecimals;
  160.     short        realExp;
  161.     char        decimals[32];
  162.     int            lastNonZero;
  163.     int            deciCount;
  164.     int            actDecimals,firstDecimals;
  165.     char        *sourceDecimals;
  166.     char        theDec;
  167.         
  168.  
  169.     NumberToDecimalRecord(n,&myDecimals, maxDecimals);
  170.     
  171.     if(myDecimals.exp+myDecimals.sig.length > integerPart)
  172.     {    
  173.         realExp = myDecimals.exp + myDecimals.sig.length - 1;
  174.         myDecimals.exp -= realExp;
  175.     }
  176.     else
  177.     {    realExp = 0;
  178.     }
  179.         
  180.     dest[0] = 0; // Clear the string;
  181.  
  182.     sourceDecimals  = (char *)(myDecimals.sig.text +
  183.                                 myDecimals.sig.length +
  184.                                    myDecimals.exp);
  185.     firstDecimals = -myDecimals.sig.length - myDecimals.exp;
  186.     actDecimals = -myDecimals.exp;
  187.     if(actDecimals < 0)
  188.         actDecimals = 0;
  189.  
  190.     lastNonZero = minDecimals;
  191.     
  192.     for(deciCount = 0; deciCount < maxDecimals; deciCount++)
  193.     {
  194.         if(deciCount >= actDecimals || deciCount < firstDecimals)
  195.         {    decimals[deciCount] = '0';
  196.         }
  197.         else
  198.         {    theDec = sourceDecimals[deciCount];
  199.             decimals[deciCount] = theDec;
  200.             if(deciCount >= lastNonZero && theDec != '0')
  201.             {    lastNonZero = deciCount+1;
  202.             }
  203.         }
  204.     }
  205.  
  206.     for(fmIndex = 1; fmIndex <= formatString[0]; fmIndex++)
  207.     {    switch(formatString[fmIndex])
  208.         {
  209.             case '-':    //    sign prefix
  210.                 if(myDecimals.sgn)
  211.                     AppendBytes(dest, negativePrefix[0],negativePrefix+1);
  212.                 else
  213.                     AppendBytes(dest, positivePrefix[0],positivePrefix+1);
  214.                 break;
  215.             case ')':    //    sign postfix
  216.                 if(myDecimals.sgn)
  217.                     AppendBytes(dest, negativePostfix[0],negativePostfix+1);
  218.                 else
  219.                     AppendBytes(dest, positivePostfix[0],positivePostfix+1);
  220.                 break;
  221.             case '.':
  222.                 if(lastNonZero != 0)
  223.                     AppendBytes(dest, decimalSign[0],decimalSign+1);
  224.                 break;
  225.             case '$':
  226.                 AppendBytes(dest, currencyPrefix[0],currencyPrefix+1);
  227.                 break;
  228.             case '£':
  229.                 AppendBytes(dest, currencyPostfix[0],currencyPostfix+1);
  230.                 break;
  231.             case '1':
  232.                 j = myDecimals.sig.length + myDecimals.exp;
  233.                 i = 0;
  234.                 
  235.                 if(j<=0)
  236.                 {    char    zero = '0';
  237.                 
  238.                     AppendBytes(dest, 1, &zero);
  239.                 }
  240.                 else
  241.                 {
  242.                     while(j > 0)
  243.                     {    int        chunk;
  244.                     
  245.                         chunk = j % 3;
  246.                         if(chunk == 0) chunk = 3;
  247.                         
  248.                         if(i+chunk < myDecimals.sig.length)
  249.                         {    AppendBytes(dest, chunk, myDecimals.sig.text+i);
  250.                         }
  251.                         else
  252.                         {    int        partOne;
  253.                             long    zeros='0000';
  254.                             
  255.                             partOne = myDecimals.sig.length - i;
  256.                             if(partOne < 0) partOne = 0;
  257.                             
  258.                             if(partOne)
  259.                                 AppendBytes(dest, chunk, myDecimals.sig.text+i);
  260.  
  261.                             AppendBytes(dest, chunk-partOne, (char *)&zeros);
  262.                         }
  263.                         
  264.                         i += chunk;
  265.                         j -= chunk;
  266.                         
  267.                         if(j)
  268.                             AppendBytes(dest, thousandsSeparator[0], thousandsSeparator+1);
  269.                     }
  270.                 }
  271.                 break;
  272.             case '0':
  273.                 AppendBytes(dest, lastNonZero, decimals);
  274.                 break;
  275.             case 'E':
  276.             case 'e':
  277.                 if(realExp != 0)
  278.                 {    char    expon[32];
  279.                     int        len;
  280.                 
  281.                     NumToString(realExp,expon);
  282.                     len = expon[0] +1;
  283.                     expon[0] = formatString[fmIndex];
  284.                     AppendBytes(dest, len, expon);
  285.                 }    
  286.                 break;
  287.         }
  288.     }
  289. }
  290.